package com.buddha.api.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.buddha.api.common.Constants;
import com.buddha.api.common.Result;
import com.buddha.api.dto.PassDto;
import com.buddha.api.entity.Role;
import com.buddha.api.entity.User;
import com.buddha.api.entity.UserRole;
import com.buddha.api.service.impl.RoleServiceImpl;
import com.buddha.api.service.impl.UserRoleServiceImpl;
import com.buddha.api.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author mybatis-plus
 * @since 2023-07-06
 */
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private RoleServiceImpl roleService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private UserRoleServiceImpl userRoleService;

    @PreAuthorize("hasAuthority('sys:user:save')")
    @PostMapping("/save")
    public Result saveUser(@Validated @RequestBody User user){
        User one = userService.getOne(new QueryWrapper<User>().eq("phone", user.getPhone()));
        if (one != null){
            return Result.error(Constants.CODE_400, "该用户已存在");
        }
        user.setCreated(LocalDateTime.now());
        if (user.getState() == null){
            user.setState(Constants.STATE_ON);
        }
        user.setPassword(bCryptPasswordEncoder.encode(Constants.DEFAULT_PASSWORD));
        user.setAvatar(Constants.DEFAULT_AVATAR);
        return Result.success(userService.save(user));
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @PostMapping("/update")
    public Result updateUser(@Validated @RequestBody User user){
        user.setUpdated(LocalDateTime.now());
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        return Result.success(userService.updateById(user));
    }

    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    public Result delete(@RequestBody Integer[] ids) {
        for (Integer id : ids) {
            User user = userService.getById(id);
            userRoleService.remove(new QueryWrapper<UserRole>().eq("u_id",id));
            userService.removeById(id);
            userService.clearUserAuthority(user.getUsername());
        }
        return Result.success();
    }


    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('sys:user:list')")
    public Result findOne(@PathVariable Integer id) {
        User user = userService.getById(id);
        Assert.notNull(user,"找不到该管理员");
        List<Role> roles = roleService.findRoles(id);
        user.setRoles(roles);
        return Result.success(user);
    }

    @Transactional
    @PostMapping("/role/{userId}")
    @PreAuthorize("hasAuthority('sys:user:role')")
    public Result allocateRole(@PathVariable("userId") Integer userId,@RequestBody Integer[] roleIds){
        User user = userService.getById(userId);
        userRoleService.remove(new QueryWrapper<UserRole>().eq("u_id",userId));
        for (Integer rId : roleIds) {
            Role role = roleService.getById(rId);
            UserRole userRole = new UserRole();
            userRole.setUId(userId);
            userRole.setRId(rId);
            userRoleService.save(userRole);
        }
        userService.clearUserAuthority(user.getUsername());
        return Result.success(user);
    }

    @GetMapping("/page")
    @PreAuthorize("hasAuthority('sys:user:list')")
    public Result findPage(
            @RequestParam Integer pageNum,
            @RequestParam Integer pageSize,
            @RequestParam(defaultValue = "") String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("username",username);
        Page<User> page = userService.page(new Page<>(pageNum, pageSize), queryWrapper);
        for (User record : page.getRecords()) {
            List<Role> roles = roleService.findRoles(record.getId());
            record.setRoles(roles);
        }
        return Result.success(page);
    }

    @GetMapping("/repass/{id}")
    @PreAuthorize("hasAuthority('sys:user:repass')")
    public Result repass(@PathVariable("id") long id){

        String newPass = bCryptPasswordEncoder.encode(Constants.DEFAULT_PASSWORD);
        User user = userService.getById(id);
        user.setPassword(newPass);
        user.setUpdated(LocalDateTime.now());
        userService.clearUserAuthority(user.getUsername());
        userService.updateById(user);
        return Result.success();
    }


    @PostMapping("/updatePass")
    public Result updatePass(@Validated @RequestBody PassDto passDto, Principal principal) {

        User sysUser = userService.findByUsername(principal.getName());

        boolean matches = bCryptPasswordEncoder.matches(passDto.getCurrentPass(), sysUser.getPassword());
        if (!matches) {
            return Result.error(Constants.CODE_400,"旧密码不正确");
        }

        sysUser.setPassword(bCryptPasswordEncoder.encode(passDto.getPassword()));
        sysUser.setUpdated(LocalDateTime.now());

        userService.updateById(sysUser);
        userService.clearUserAuthority(sysUser.getUsername());

        return Result.success("");
    }



}
